/**
 * 视频播放管理器
 * 防止并发播放请求导致的DOMException
 */

class VideoPlayManager {
  constructor() {
    this.playingVideos = new Set()
    this.playQueue = new Map() // video -> promise
  }

  /**
   * 安全播放视频
   * @param {HTMLVideoElement} video - 视频元素
   * @param {Object} options - 播放选项
   * @returns {Promise<boolean>} 播放是否成功
   */
  async playVideo(video, options = {}) {
    if (!video) {
      throw new Error('视频元素不存在')
    }

    // 如果已经在播放队列中，等待完成
    if (this.playQueue.has(video)) {
      console.log('🔄 视频已在播放队列中，等待完成...')
      await this.playQueue.get(video)
      return true
    }

    // 创建播放Promise
    const playPromise = this._doPlayVideo(video, options)
    this.playQueue.set(video, playPromise)

    try {
      const result = await playPromise
      return result
    } finally {
      this.playQueue.delete(video)
    }
  }

  /**
   * 实际执行播放
   * @private
   */
  async _doPlayVideo(video, options) {
    try {
      // 强制停止当前播放
      video.pause()
      
      // 等待停止完成
      await new Promise(resolve => setTimeout(resolve, 100))
      
      // 设置选项
      if (options.muted !== undefined) {
        video.muted = options.muted
      }
      
      // 确保视频已加载
      if (video.readyState < 2) {
        console.log('⚠️ 视频未准备好，等待加载...')
        await this._waitForVideoReady(video)
      }
      
      // 播放视频
      const playPromise = video.play()
      if (playPromise) {
        await playPromise
      }
      
      this.playingVideos.add(video)
      console.log('✅ 视频播放成功')
      return true
      
    } catch (error) {
      console.error('❌ 视频播放失败:', error)
      
      // 如果是NotAllowedError，尝试静音播放
      if (error.name === 'NotAllowedError' && !video.muted) {
        console.log('🔄 尝试静音播放...')
        video.muted = true
        try {
          const playPromise = video.play()
          if (playPromise) {
            await playPromise
          }
          this.playingVideos.add(video)
          console.log('✅ 静音视频播放成功')
          return true
        } catch (mutedError) {
          console.error('❌ 静音视频播放也失败:', mutedError)
          throw mutedError
        }
      }
      
      throw error
    }
  }

  /**
   * 等待视频准备就绪
   * @private
   */
  async _waitForVideoReady(video, timeout = 5000) {
    return new Promise((resolve, reject) => {
      const timeoutId = setTimeout(() => {
        reject(new Error('视频加载超时'))
      }, timeout)

      const onCanPlay = () => {
        clearTimeout(timeoutId)
        video.removeEventListener('canplay', onCanPlay)
        video.removeEventListener('error', onError)
        resolve()
      }

      const onError = (error) => {
        clearTimeout(timeoutId)
        video.removeEventListener('canplay', onCanPlay)
        video.removeEventListener('error', onError)
        reject(error)
      }

      if (video.readyState >= 2) {
        clearTimeout(timeoutId)
        resolve()
        return
      }

      video.addEventListener('canplay', onCanPlay)
      video.addEventListener('error', onError)
    })
  }

  /**
   * 停止视频播放
   */
  stopVideo(video) {
    if (video) {
      video.pause()
      this.playingVideos.delete(video)
    }
  }

  /**
   * 停止所有视频播放
   */
  stopAllVideos() {
    this.playingVideos.forEach(video => {
      video.pause()
    })
    this.playingVideos.clear()
  }
}

// 创建全局实例
const videoPlayManager = new VideoPlayManager()

// 导出函数
export const safePlayVideo = (video, options = {}) => {
  return videoPlayManager.playVideo(video, options)
}

export const setVideoStreamAndPlay = async (video, stream, options = {}) => {
  if (!video || !stream) {
    throw new Error('视频元素或媒体流不存在')
  }

  try {
    // 设置视频源
    video.srcObject = stream
    
    // 等待视频加载
    await new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        reject(new Error('视频加载超时'))
      }, 5000)
      
      video.onloadedmetadata = () => {
        clearTimeout(timeout)
        resolve()
      }
      
      video.onerror = (error) => {
        clearTimeout(timeout)
        reject(error)
      }
    })
    
    // 安全播放
    await safePlayVideo(video, options)
    
  } catch (error) {
    console.error('❌ 设置视频流并播放失败:', error)
    throw error
  }
}

export default videoPlayManager
